import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;

import java.awt.*;
import java.io.*;
import java.util.Map.Entry;
import java.util.*;
public class PoneBookJFrame1 extends JFrame {
    private JList<String> jList;
    private JTextField nameText;
    private JTable table;
    //100个表格模型
    private MyTableModel [] model = new MyTableModel[100];
    private HashMap<String,Friend>friends = new HashMap();
    private MyTableModel model_for_search;

    private PoneBookJFrame1(){
        super("电话簿");
        this.setSize(600,300);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);

        JPanel rightPanel = new JPanel(new BorderLayout());
        JPanel bottomPanel = new JPanel(new GridLayout(2,1));
        DefaultListModel <String>dlm = new DefaultListModel<>();
        dlm.addElement("全部");
        dlm.addElement("张");
        dlm.addElement("王");
        dlm.addElement("李");
        dlm.addElement("郑");
        dlm.addElement("朱");

        jList = new JList<>();
        jList.setModel(dlm);
        JScrollPane leftPanel = new JScrollPane(jList);
        jList.setFont(new Font("等线", Font.PLAIN, 18));

        init();//初始化表格
        table = new JTable(model[0]);
        JScrollPane topPanel = new JScrollPane(table);
        table.setRowHeight(25);
        DefaultTableCellRenderer r = new DefaultTableCellRenderer();
        r.setHorizontalAlignment(JLabel.CENTER);
        table.setDefaultRenderer(Object.class, r);//设置居中方式
        table.setFont(new Font("等线", Font.PLAIN, 18));

        JLabel name = new JLabel("姓名");
        name.setHorizontalAlignment(JTextField.CENTER);
        nameText = new JTextField("");
        nameText.setHorizontalAlignment(JTextField.CENTER);
        JLabel phone = new JLabel("电话号码");
        phone.setHorizontalAlignment(JTextField.CENTER);
        JTextField phoneText = new JTextField("");
        phoneText.setHorizontalAlignment(JTextField.CENTER);
        JButton buttonAdd = new JButton("添加");
        JButton buttonDelete = new JButton("删除");
        JButton buttonUpdate = new JButton("修改");
        JButton buttonSearch = new JButton("按电话号码查找");

        bottomPanel.add(name);
        bottomPanel.add(nameText);
        bottomPanel.add(phone);
        bottomPanel.add(phoneText);
        bottomPanel.add(buttonAdd);
        bottomPanel.add(buttonDelete);
        bottomPanel.add(buttonUpdate);
        bottomPanel.add(buttonSearch);

        //垂直隔条
        JSplitPane split2 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, topPanel,bottomPanel);
        //水平隔条
        JSplitPane split1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,leftPanel,rightPanel);
        split1.setDividerLocation(50);
        split2.setDividerLocation(160);
        this.getContentPane().add(split1,BorderLayout.CENTER);
        split1.setRightComponent(split2);

        /*
         * 列表框选择监听器
         * */
        jList.addListSelectionListener(e -> {
            if(e.getValueIsAdjusting()){
                int index = jList.getLeadSelectionIndex();
                table.setModel(model[index]);
            }
        });
        /*
         * 查询朋友的监听器
         * */
        buttonSearch.addActionListener(e -> {
            if(phoneText.getText().length()==11){
                model_for_search = new MyTableModel();
                model_for_search.addColumn("姓名");
                model_for_search.addColumn("电话号码");
                friends.forEach((key,value)->{
                    if(value.getPhoneNumber().equals(phoneText.getText()))
                        model_for_search.addRow(new Object[]{value.getName(), value.getPhoneNumber()});
                    table.setModel(model_for_search);
                });
            }
           else {
               JOptionPane.showMessageDialog(null,"电话号码不符合规范");
            }
        });
        /*
         * 删除朋友的监听器
         * */
        buttonDelete.addActionListener(e -> {
            //删除散列表里面的friend对象
            if(table.getSelectedRows().length>0){
                String str = table.getValueAt(table.getSelectedRow(),0).toString();
                Set<Entry<String, Friend>> set= friends.entrySet();
                java.util.Iterator<Entry<String, Friend>> iterator=set.iterator();
                while(iterator.hasNext()){
                    Entry<String, Friend> entry=iterator.next();
                    String firstName =  entry.getKey();
                    if(firstName.equals(str)){
                        iterator.remove();
                    }
                }
                //更新视图
                updateAllModel();
                writeObjectToFile(friends);
            }
            else
                JOptionPane.showMessageDialog(null, "未选中要删除的列");
        });
        /*
         * 添加朋友的监听器
         * */
        buttonAdd.addActionListener(e -> {
            String key = nameText.getText();//获取姓名
            if(key.length()!=0&&phoneText.getText().length()==11){
                Friend friend = new Friend(key,phoneText.getText());//获取Friend对象
                ListModel<String> m = jList.getModel();
                int flag = 0;
                for (int i = 0; i < m.getSize(); i++) {
                    if(key.substring(0,1).equals(m.getElementAt(i)))
                        flag++;
                }
                //代表原来对索引里面有这个姓名
                if(flag==1) {
                    friends.put(key, friend);
                }
                //代表原来索引呢里面没有这个姓名
                else{
                    dlm.addElement(key.substring(0,1));
                    jList.setModel(dlm);//更新索引
                    friends.put(key, friend);//散列表添加一项内容，key为姓名，value为friend对象
                }
                //更新视图
                updateAllModel();
                writeObjectToFile(friends);
            }
            else if(key.length()==0) {
                JOptionPane.showMessageDialog(null,"姓名不能为空");
            }
            else {
                JOptionPane.showMessageDialog(null,"电话号码不符合规范");
            }
        });
        /*
         * 修改朋友的监听器
         * */
        buttonUpdate.addActionListener(e -> {
            ListModel<String> m=jList.getModel();
            int [] count = new int[m.getSize()];
            ArrayList<Integer>[] modelIndex = new ArrayList[m.getSize()];
            int all = 0;
            for (int i = 0; i < m.getSize(); i++) {
                count[i] = model[i].getEditedIndex().size();//用来存储第i个索引修改的个数
                modelIndex[i] = model[i].getEditedIndex();//用来存储第i个索引修改的几个地方
                if(count[i]>0) {
                    all++;
                }
            }
            /*
            * 当修改的是索引的结果
            * */
            if(all>0){
                for (int i = 0; i <m.getSize(); i++) {//第一层循环代表最左边的第几个索引
                    for (int j = 0; j <count[i]&&count[i]>0; j++) {//第二层循环代表代表第i个索引的第几个被修改的地方
                        int index = modelIndex[i].get(j);//用来存储第i个索引修改的第j行
                        /*
                        * 这句话非常重要，没有这句话只能多次修改一个索引的内容
                        * */
                        table.setModel(model[i]);

                        String nameValue =table.getValueAt(index,0).toString();//被修改的人的姓名
                        String phoneValue = table.getValueAt(index,1).toString();//修改后的手机号
                        friends.forEach((key,value)->{

                            if(value.getName().equals(nameValue)){
                                value.setPhoneNumber(phoneValue);
                            }
                        });
                    }
                }
            }
            try{
                all= model_for_search.getEditedIndex().size();
                for (int i = 0; i <all; i++) {
                    int index = model_for_search.getEditedIndex().get(i);
                    String nameValue =table.getValueAt(index,0).toString();//被修改的人的姓名
                    String phoneValue = table.getValueAt(index,1).toString();//修改后的手机号

                    friends.forEach((key,value)->{

                        if(value.getName().equals(nameValue)){
                            value.setPhoneNumber(phoneValue);
                        }
                    });

                }
            }catch (NullPointerException e1){//空对象异常
                System.out.print(" ");
            }

            //更新视图
            updateAllModel();

            writeObjectToFile(friends);
        });

        this.setVisible(true);
    }

    private static Object readObjectFromFile(String fileName)
    {
        Object temp=null;
        File file =new File(fileName);
        FileInputStream in;
        try {
            in = new FileInputStream(file);
            ObjectInputStream objIn=new ObjectInputStream(in);
            temp=objIn.readObject();
            objIn.close();
            System.out.println("载入文件成功!");
        } catch (IOException e) {
            System.out.println("载入文件失败!");
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return temp;
    }

    private static void writeObjectToFile(Object obj)
    {
        File file =new File("phone_book.dat");
        FileOutputStream out;
        try {
            out = new FileOutputStream(file);
            ObjectOutputStream objOut=new ObjectOutputStream(out);
            objOut.writeObject(obj);
            objOut.flush();
            objOut.close();
            System.out.println("写入成功!");
        } catch (IOException e) {
            System.out.println("写入失败");
            e.printStackTrace();
        }
    }
    /**
    * 传入该模型对应的索引,返回该模型
    * */
    private MyTableModel updateModel(String firstName){
        MyTableModel model = new MyTableModel();
        model.addColumn("姓名");
        model.addColumn("电话号码");
        friends.forEach((key,value)->{
            //如果索引相等，则添加行
            if(key.substring(0,1).equals(firstName))
                model.addRow(new Object[]{value.getName(), value.getPhoneNumber()});
        });
        return model;
    }
    /**
    * 更新全部模型，用于更新视图
    * */
    private void updateAllModel() {
        ListModel<String> m = jList.getModel();
        model[0] = new MyTableModel();
        model[0].addColumn("姓名");
        model[0].addColumn("电话号码");
        friends.forEach((key,value)-> model[0].addRow(new Object[]{value.getName(), value.getPhoneNumber()}));
        for(int i = 1;i<m.getSize();i++) {
                model[i] = updateModel(m.getElementAt(i));
        }
        table.setModel(model[0]);
    }
    /**
     * 初始化表格
     * */
    private void init(){
        File file = new File("phone_book.dat");
        /*
         * 如果文件存在
         * 对HashMap进行读取
         * */
        if(file.exists())
            friends = (HashMap<String, Friend>) readObjectFromFile("phone_book.dat");
        /*
        * 否则初始化为如下
        * */
        else{
            friends.put("张东璨",new Friend("张东璨","15950803241"));
            friends.put("王伟",new Friend("王伟","15256482367"));
            friends.put("李晓明",new Friend("李晓明","15951737201"));
            friends.put("郑浩",new Friend("郑浩","17857946305"));
            friends.put("朱红",new Friend("朱红","17805188216"));
        }
        for (int i = 0; i <100; i++) {
            model[i] = new MyTableModel();
        }

        for (int i = 0; i <100; i++) {
            model[i].addColumn("姓名");
            model[i].addColumn("电话号码");
        }

        //model[0]代表全部
        friends.forEach((key,value)->{
            model[0].addRow(new Object[]{value.getName(), value.getPhoneNumber()});
            ListModel<String> m = jList.getModel();
            for(int i =0 ;i<m.getSize();i++) {
                if(key.substring(0,1).equals(m.getElementAt(i)))
                    model[i].addRow(new Object[]{value.getName(), value.getPhoneNumber()});
        }
        });

    }
    public static void main(String[] args) {
        new PoneBookJFrame1();

    }
}
